/*!
 * \file ParserXeleSkt.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 * 
 * \brief Xele Socket行情解析器头文件
 * 
 * \details 该文件定义了ParserXeleSkt类，是WonderTrader系统中用于接收Xele/SHFE行情数据的核心组件：
 *          - 实现IParserApi接口，提供统一的行情解析服务
 *          - 专门用于上海期货交易所(SHFE)的Xele行情系统
 *          - 采用TCP+UDP双协议架构：TCP获取快照，UDP接收实时行情
 *          - 支持UDP组播方式接收高频实时行情数据
 *          - 支持多种Xele数据格式：普通行情、深度行情、快照数据
 *          - 使用boost::asio异步网络编程框架
 *          - 提供价格精度处理和数据缓存机制
 *          - 支持合约订阅管理和数据过滤
 *          - 适用于SHFE期货和期权的高频交易场景
 * 
 * \note Xele是上海期货交易所的新一代行情系统，具有低延迟特性
 * \warning 需要正确配置组播地址和本地网卡地址
 */
#pragma once
#include "../Includes/IParserApi.h"
#include "../Includes/WTSCollection.hpp"
#include "../Share/StdUtils.hpp"

#include <queue>

#include <boost/asio.hpp>
#include <boost/array.hpp>
#include <boost/asio/io_service.hpp>

USING_NS_WTP;
using namespace boost::asio;

/*!
 * \class ParserXeleSkt
 * \brief Xele Socket行情解析器类
 * 
 * \details ParserXeleSkt是WonderTrader系统中用于接收Xele/SHFE行情数据的核心组件，主要功能包括：
 *          - Xele行情协议解析：专门处理上海期货交易所Xele系统的行情数据格式
 *          - 双协议网络架构：TCP连接用于获取市场快照数据，UDP组播用于接收实时行情推送
 *          - 组播数据接收：支持UDP组播方式接收高频实时行情，降低网络延迟
 *          - 快照数据预加载：通过TCP连接预先获取市场快照，确保数据完整性
 *          - 多类型数据处理：支持心跳、普通行情、深度行情、静态数据、快照等多种数据类型
 *          - 价格精度管理：根据合约信息自动处理价格刻度和精度转换
 *          - 数据缓存机制：使用TickCache缓存历史行情数据，提高查询效率
 *          - 合约管理集成：与基础数据管理器集成，自动获取合约信息
 *          - 异步网络编程：基于boost::asio的高性能异步网络处理
 *          - 错误恢复机制：提供网络异常检测和自动重连功能
 * 
 * \note 该类专门用于SHFE的Xele行情系统，具有极低的延迟特性
 * \warning 组播接收需要正确配置网络接口和组播地址
 * \see IParserApi boost::asio
 */
class ParserXeleSkt : public IParserApi
{
public:
	/*!
	 * \brief 构造函数
	 * 
	 * 初始化ParserXeleSkt实例，设置默认参数和网络组件
	 */
	ParserXeleSkt();
	
	/*!
	 * \brief 析构函数
	 * 
	 * 清理资源，确保正确断开连接和释放套接字
	 */
	~ParserXeleSkt();

	// IParserApi 接口实现
public:
	/*!
	 * \brief 初始化Xele行情解析器
	 * \param config 配置参数对象
	 * \return 是否初始化成功
	 * 
	 * \details 从配置对象中读取以下参数：
	 *          - tcp_host: TCP服务器主机地址（用于获取快照数据）
	 *          - tcp_port: TCP服务器端口号
	 *          - mcast_host: UDP组播地址（用于实时行情接收）
	 *          - mcast_port: UDP组播端口号
	 *          - local_host: 本地网卡地址（用于组播绑定）
	 *          - gpsize: 分组大小（默认1000，用于日志输出频率控制）
	 *          - 初始化TCP和UDP终端点配置
	 *          - 配置组播接收的网络地址
	 * 
	 * \note Xele系统需要配置TCP和UDP两个不同的连接
	 * \warning 必须确保组播地址配置正确且网络可达
	 */
	virtual bool init(WTSVariant* config) override;

	/*!
	 * \brief 释放资源
	 * 
	 * 释放Xele行情解析器占用的所有资源
	 */
	virtual void release() override;

	/*!
	 * \brief 建立连接
	 * \return 是否连接成功
	 * 
	 * 启动Xele网络连接，包括快照准备和组播接收
	 */
	virtual bool connect() override;

	/*!
	 * \brief 断开连接
	 * \return 是否断开成功
	 * 
	 * 断开Xele连接，关闭套接字，停止网络处理
	 */
	virtual bool disconnect() override;

	/*!
	 * \brief 检查连接状态
	 * \return 是否已连接
	 * 
	 * 返回当前Xele连接状态
	 */
	virtual bool isConnected() override;

	/*!
	 * \brief 订阅行情数据
	 * \param vecSymbols 要订阅的合约代码集合
	 * 
	 * 添加合约代码到订阅列表，支持批量订阅
	 */
	virtual void subscribe(const CodeSet &vecSymbols) override;
	
	/*!
	 * \brief 退订行情数据
	 * \param vecSymbols 要退订的合约代码集合
	 * 
	 * 从订阅列表中移除合约代码
	 */
	virtual void unsubscribe(const CodeSet &vecSymbols) override;

	/*!
	 * \brief 注册行情回调接口
	 * \param listener 行情数据回调接口指针
	 * 
	 * 注册行情数据处理回调接口，用于接收处理后的行情数据
	 */
	virtual void registerSpi(IParserSpi* listener) override;


private:
	/*!
	 * \brief 处理UDP组播数据接收
	 * \param e boost错误代码
	 * \param bytes_transferred 接收到的字节数
	 * 
	 * 异步处理UDP组播数据接收，解析Xele实时行情数据
	 */
	void	handle_udp_read(const boost::system::error_code& e, std::size_t bytes_transferred);

	/*!
	 * \brief 准备市场快照数据
	 * \return 是否准备成功
	 * 
	 * 通过TCP连接获取市场快照数据，初始化价格精度和缓存
	 */
	bool	prepare();

	/*!
	 * \brief 重新连接Xele服务器
	 * \return 是否重连成功
	 * 
	 * 重新建立UDP组播连接，包括组播组加入和异步接收启动
	 */
	bool	reconnect();

	/*!
	 * \brief 解析Xele数据缓冲区
	 * \param length 数据长度
	 * 
	 * 解析接收到的Xele数据包，根据类型分发到不同处理函数
	 */
	void	extract_buffer(uint32_t length);

private:
	/*!
	 * \brief 处理连接成功事件
	 * 
	 * 连接成功后的回调处理
	 */
	void	doOnConnected();
	
	/*!
	 * \brief 处理连接断开事件
	 * 
	 * 连接断开后的回调处理
	 */
	void	doOnDisconnected();

private:
	std::string	_tcp_host;		///< TCP服务器主机地址（快照数据）
	int			_tcp_port;		///< TCP服务器端口号
	std::string	_mcast_host;	///< UDP组播地址（实时行情）
	int			_mcast_port;	///< UDP组播端口号
	std::string	_local_host;	///< 本地网卡地址（组播绑定）
	uint32_t	_gpsize;		///< 分组大小（日志输出频率控制）

	ip::udp::endpoint	_mcast_ep;		///< 组播终端点
	ip::udp::endpoint	_udp_ep;		///< UDP终端点
	ip::tcp::endpoint	_tcp_ep;		///< TCP终端点
	io_service			_io_service;	///< boost::asio IO服务对象

	io_service::strand	_strand;		///< boost::asio线程安全串行化对象

	ip::udp::socket*	_udp_socket;	///< UDP套接字指针

	boost::array<char, 4096> _udp_buffer;	///< UDP数据接收缓冲区

	IParserSpi*		_sink;			///< 行情数据回调接口指针
	IBaseDataMgr*	_bd_mgr;		///< 基础数据管理器指针
	bool			_stopped;		///< 停止标志
	bool			_prepared;		///< 快照准备完成标志

	CodeSet			_set_subs;		///< 订阅合约代码集合
	StdThreadPtr	_thrd_parser;	///< 网络处理线程指针

	typedef WTSHashMap<int>	TickCache;		///< Tick数据缓存类型定义
	TickCache*		_tick_cache;			///< Tick数据缓存指针

	faster_hashmap<int, double> _price_scales;	///< 价格精度映射表（合约编号->价格刻度）
};

